package com.wushijia.classload;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/**
 * 反射和方法句柄之间的区别在于处理访问控制的方式，Lookup对象只会返回在创建这个对象的上下文可以访问的方法，没有任何方式可以破坏这个规则
 *  方法句柄会在构建查找上下文时检查访问权限，不会为没有正确访问权限的方法创建句柄
 */
public class MethodTest {

  public static void main(String[] args) throws Throwable {
    Object o = "a";
    //方法的类型签名
    MethodType methodType = MethodType.methodType(int.class);
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    //方法句柄
    MethodHandle methodHandle = lookup.findVirtual(o.getClass(), "hashCode", methodType);
    //invokeExact直接调用方法句柄
    String str = (String) o;
    int ret1 = (int) methodHandle.invokeExact(str);
    System.out.println(ret1);
    //而invoke会在需要时修改调用参数，比如会放大参数的类型
    int ret = (int) methodHandle.invoke(o);
    System.out.println(ret);
  }
}
